package com.peking.donations.plugins.pay.wx.web.controller;

import com.alibaba.druid.util.StringUtils;
import com.google.common.collect.Maps;
import com.peking.donations.base.security.LoggedUser;
import com.peking.donations.base.util.SecurityUtil;
import com.peking.donations.base.util.SequenceUtil;
import com.peking.donations.base.util.Signature;
import com.peking.donations.base.vo.AjaxResponse;
import com.peking.donations.model.DonationSaving;
import com.peking.donations.plugins.pay.wx.constants.CacheNames;
import com.peking.donations.plugins.pay.wx.constants.TradeType;
import com.peking.donations.plugins.pay.wx.protocol.pay.UnifiedPayRepData;
import com.peking.donations.plugins.pay.wx.protocol.pay.UnifiedPayReqData;
import com.peking.donations.plugins.pay.wx.service.AuthorizeService;
import com.peking.donations.plugins.pay.wx.service.UnifiedPayService;
import com.peking.donations.plugins.pay.wx.utils.Configure;
import com.peking.donations.plugins.pay.wx.utils.GlobalConfigure;
import com.peking.donations.plugins.pay.wx.utils.WxpayException;
import com.peking.donations.service.BizService;
import com.peking.donations.vo.PayVo;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * Created by YGR on 16/3/10.
 */
@Controller
@RequestMapping("/peking/prepay/")
public class PrepayController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    UnifiedPayService unifiedPayService;

    @Autowired
    AuthorizeService authorizeService;

    @Autowired
    BizService bizService;

    @Autowired
    Configure configure;

    @Autowired
    GlobalConfigure globalConfigure;

    @Autowired
    CacheManager cacheManager;

    @Value("${global.encryptkey}")
    private String encryptkey;

    @RequestMapping(value = "/wx/js")
    public String doWxJsPrepay(HttpServletRequest request, ModelMap modelMap,
            @RequestParam(name = "transactionId") String transactionId) throws Exception {
        DonationSaving saving = bizService.findSavingByTransactionId(transactionId);
        if (null == saving) {
            throw new Exception("订单不存在!");
        }
        LoggedUser user = SecurityUtil.getCurrentUser();
        UnifiedPayReqData reqData = new UnifiedPayReqData();
        reqData.setAppid(configure.getAppID());
        // reqData.setOpenid(user.getOpenId());
        reqData.setNotify_url(configure.getNotifyUrl());
        reqData.setSpbill_create_ip(globalConfigure.getHostip());
        reqData.setTotal_fee(new Long(saving.getAmount()).intValue() * saving.getShare());
        reqData.setBody("北京大学教育基金会");
        reqData.setMch_id(configure.getMchID());
        reqData.setNonce_str(SequenceUtil.getRandomStringByLength(3));
        reqData.setOut_trade_no(saving.getTransactionId());
        reqData.setTrade_type(TradeType.NATIVE.name());

        try {
            UnifiedPayRepData repData = unifiedPayService.sendPrepayPost(reqData);
            Map<String, String> m = Maps.newHashMap();
            m.put("appId", repData.appid);
            m.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            m.put("nonceStr", SequenceUtil.getRandomStringByLength(6));
            m.put("package", String.format("prepay_id=%s", repData.prepay_id));
            m.put("signType", "MD5");
            m.put("paySign", Signature.getSign(m, configure.getKey()));

            modelMap.addAttribute("picUrl", repData.code_url);
            modelMap.addAttribute("appId", m.get("appId"));
            modelMap.addAttribute("timeStamp", m.get("timeStamp"));
            modelMap.addAttribute("package", m.get("package"));
            modelMap.addAttribute("nonceStr", m.get("nonceStr"));
            modelMap.addAttribute("signType", m.get("signType"));
            modelMap.addAttribute("paySign", m.get("paySign"));
        } catch (WxpayException e) {
            e.printStackTrace();
        }
        modelMap.addAttribute("callId", saving.getOrderId() != null ? saving.getOrderId() : "");
        modelMap.addAttribute("tid", saving.getTransactionId());
        return "wx/payJSBridgeCode";
    }

    /**
     * 微信预支付二维码()
     * 
     * @return
     */
    @RequestMapping(value = "/qrcode/img", method = RequestMethod.GET)
    public void wechatPay(HttpServletRequest req, HttpServletResponse res, @RequestParam(name = "url") String url)
            throws Exception {
        try {
            ByteArrayOutputStream out = QRCode.from(url).to(ImageType.PNG).withSize(240, 240).stream();
            res.setContentType("image/png");
            res.setContentLength(out.size());
            OutputStream outStream = res.getOutputStream();
            outStream.write(out.toByteArray());
            outStream.flush();
            outStream.close();
        } catch (Exception e) {
            logger.error("#获取微信支付二维码失败。", e);
        }
    }

    @RequestMapping(value = "/qrcode/wxpay/isFinish", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResponse wechatPayFinish(@RequestBody PayVo payVo) {
        String tid = payVo.getTid();
        if (StringUtils.isEmpty(tid)) {
            AjaxResponse ajax = new AjaxResponse("failed", "微信支付失败!订单不存在", AjaxResponse.STATE_SUCCESS);
            return ajax;
        }
        // tid = EncryptUtil.decrypt(tid, encryptKey);
        Cache cache = cacheManager.getCache(CacheNames.PAY_SUCCESS_TRANSACTIONS.name());
        Cache.ValueWrapper value = cache.get(tid);
        Cache cache1 = cacheManager.getCache(CacheNames.PAY_FAILED_TRANSACTIONS.name());
        Cache.ValueWrapper value1 = cache1.get(tid);
        AjaxResponse ajax = null;
        logger.info("#####查询微信支付是否完成，订单号:" + tid);
        logger.info("#####存单信息：payTrans:" + value, "payFailed:" + value1);
        if (value == null && value1 == null) {
            ajax = new AjaxResponse(null, "正在支付中...", AjaxResponse.STATE_SUCCESS);
            return ajax;
        } else {
            if (value != null) {
                ajax = new AjaxResponse("success", "微信支付成功!", AjaxResponse.STATE_SUCCESS);
                return ajax;
            } else {
                ajax = new AjaxResponse("failed", "微信支付失败!", AjaxResponse.STATE_SUCCESS);
                return ajax;
            }
        }
    }

}
